<template>
  <el-dialog
    v-model="visible"
    :title="title"
    width="50%"
    :before-close="handleClose"
  >
    <el-form :model="formData" label-width="120px">
      <el-form-item label="索引名称" required>
        <el-input
          v-model="formData.name"
          placeholder="请输入索引名称"
          :readonly="!isNew"
        />
      </el-form-item>
      <el-form-item label="动态映射">
        <el-switch v-model="formData.dynamic" />
      </el-form-item>

      <el-divider>字段映射</el-divider>

      <el-form-item
        v-for="(item, index) in propertyItems"
        :key="item.key"
        :label="`字段 ${index + 1}`"
      >
        <GapedRow>
          <el-input
            v-model="item.mapping.fieldName"
            placeholder="字段名"
            style="width: 120px"
          />
          <el-select
            v-model="item.mapping.type"
            placeholder="类型"
            style="width: 120px"
          >
            <el-option
              v-for="type in fieldTypes"
              :key="type"
              :label="type"
              :value="type"
            />
          </el-select>
          <el-input
            v-model="item.mapping.analyzer"
            placeholder="分析器"
            style="width: 120px"
          />
          <el-input
            v-model="item.mapping.format"
            placeholder="格式"
            style="width: 120px"
          />
          <el-switch v-model="item.mapping.index" active-text="索引" />
          <el-button type="danger" @click="removeField(index)">删除</el-button>
        </GapedRow>
      </el-form-item>

      <el-form-item>
        <el-button type="primary" @click="addField">添加字段</el-button>
      </el-form-item>
    </el-form>

    <template #footer>
      <span class="dialog-footer">
        <el-button @click="handleClose">取消</el-button>
        <el-button type="primary" @click="handleConfirm">确定</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, reactive, defineEmits } from 'vue'
import { GapedRow } from '@/core/components'
import { showAlert } from '@/utils'

interface PropertyMapping {
  fieldName: string
  type: string
  analyzer?: string
  format?: string
  index?: boolean
  fields?: Record<string, PropertyMapping>
}

interface TypeMapping {
  name: string
  properties: Record<string, PropertyMapping>
  dynamic?: boolean
}

interface PropertyItem {
  key: string
  mapping: PropertyMapping
}

interface Props {
  confirmCallback?: (
    data: TypeMapping,
    isNew: boolean
  ) => Promise<boolean> | boolean
}

const emit = defineEmits(['closed'])
const props = defineProps<Props>()

const visible = ref(false)
const isNew = ref(false)
const title = ref('新增索引')

const fieldTypes = ref([
  'text',
  'keyword',
  'long',
  'integer',
  'short',
  'byte',
  'double',
  'float',
  'date',
  'boolean',
  'binary',
  'ip',
])

const formData = reactive<TypeMapping>({
  name: '',
  properties: {},
  dynamic: false,
})

const propertyItems = ref<PropertyItem[]>([])

const assignFormData = (obj: any) => {
  if (!obj) return

  formData.name = obj.name || ''
  formData.dynamic = obj.dynamic || false
  formData.properties = obj.properties || {}
  updatePropertyItems()
}

const updatePropertyItems = () => {
  propertyItems.value = Object.entries(formData.properties).map(
    ([key, mapping]) => ({
      key,
      mapping,
    })
  )
}

const show = (obj: any | undefined = undefined) => {
  console.log('show-data', obj)
  isNew.value = !obj
  resetForm()
  assignFormData(obj)
  visible.value = true
}

const resetForm = () => {
  formData.name = ''
  formData.dynamic = false
  formData.properties = {}
  propertyItems.value = []
}

const addField = () => {
  const fieldKey = `field_${propertyItems.value.length + 1}`
  propertyItems.value.push({
    key: fieldKey,
    mapping: {
      fieldName: '',
      type: 'text',
    },
  })
}

const removeField = (index: number) => {
  propertyItems.value.splice(index, 1)
}

const handleClose = (needUpdate: boolean = false) => {
  visible.value = false
  emit('closed', needUpdate)
}

const isValid = () => {
  if (!formData.name.trim()) {
    showAlert('索引名称不能为空')
    return false
  }

  if (propertyItems.value.length === 0) {
    showAlert('必需包含至少一个字段')
    return false
  }

  const fieldNames = propertyItems.value.map(item => item.mapping.fieldName)

  if (fieldNames.some(name => !name.trim())) {
    showAlert('字段名不能为空')
    return false
  }

  const uniqueFieldNames = new Set(fieldNames)
  if (fieldNames.length !== uniqueFieldNames.size) {
    showAlert('存在重复的字段名，请修改后再提交')
    return false
  }

  return true
}

const handleConfirm = async () => {
  formData.properties = propertyItems.value.reduce(
    (acc, item) => {
      acc[item.mapping.fieldName] = item.mapping
      return acc
    },
    {} as Record<string, PropertyMapping>
  )

  if (!isValid()) return

  if (props.confirmCallback) {
    const shouldClose = await props.confirmCallback(formData, isNew.value)
    if (shouldClose) {
      handleClose(true)
    }
  } else {
    handleClose(false)
  }
}

defineExpose({
  show,
})
</script>
